﻿//-----------------------------------------------------------------------
// <copyright file="Issue.cs">
//     Copyright (c) Nicole Calinoiu. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Globalization;
using System.Xml;

using Microsoft.FxCop.Sdk;
using Microsoft.VisualStudio.CodeAnalysis.Extensibility;

namespace Bordecal.FxCop.Sdk.Testing
{
	/// <summary>
	/// Represents a rule violation issue found by FxCop.
	/// </summary>
	internal sealed class Issue
	{
		internal Issue(Message parent, XmlElement element)
		{
			if (parent == null)
			{
				throw new ArgumentNullException("parent");
			}

			if (element == null)
			{
				throw new ArgumentNullException("element");
			}

			this.Message = parent;
			this.Certainty = int.Parse(element.GetAttribute("Certainty"), CultureInfo.InvariantCulture);
			this.File = element.GetAttribute("File") ?? string.Empty;

			string line = element.GetAttribute("Line");
			if (!string.IsNullOrEmpty(line))
			{
				this.Line = int.Parse(line, CultureInfo.InvariantCulture);
			}

			this.Level = element.GetAttribute("Level").ToEnum<MessageLevel>();

			this.Text = element.InnerText;
		}

		internal Issue(Message parent, int certainty, string fileName, int? lineNumber, MessageLevel messageLevel, string resolution)
		{
			if (parent == null)
			{
				throw new ArgumentNullException("parent");
			}

			this.Message = parent;
			this.Certainty = certainty;
			this.File = fileName ?? string.Empty;
			this.Line = lineNumber;
			this.Level = messageLevel;
			this.Text = resolution;
		}

		/// <summary>
		/// Gets the <see cref="Message"/> to which this issue is attached.
		/// </summary>
		internal Message Message { get; private set; }

		/// <summary>
		/// Gets the certainty level for this issue.
		/// </summary>
		internal int Certainty { get; private set; }

		/// <summary>
		/// Gets the name of the problem source file.
		/// </summary>
		internal string File { get; private set; }

		/// <summary>
		/// Gets the line number where the problem is located in the source code.
		/// </summary>
		internal int? Line { get; private set; }

		/// <summary>
		/// Gets the message level for the problem.
		/// </summary>
		internal MessageLevel Level { get; private set; }

		/// <summary>
		/// Gets the issue text.
		/// </summary>
		internal string Text { get; private set; }

		internal bool Equals(Issue issue)
		{
			bool result = false;

			// N.B.: Path is not compared since it is expected to differ on machines.
			if ((issue != null) &&
				(issue.Certainty == this.Certainty) &&
				(issue.Line == this.Line) &&
				(issue.Level == this.Level) &&
				string.Equals(issue.File, this.File, StringComparison.OrdinalIgnoreCase) &&
				string.Equals(issue.Text, this.Text, StringComparison.Ordinal))
			{
				result = issue.Message.Equals(this.Message);
			}

			return result;
		}
	}
}